net: stmmac: enable EEE in MII, GMII or RGMII only
authorJerome Brunet <jbrunet@baylibre.com>
Wed, 3 Jan 2018 15:46:29 +0000 (16:46 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 17 Jan 2018 08:38:53 +0000 (09:38 +0100)
[ Upstream commit 879626e3a52630316d817cbda7cec9a5446d1d82 ]

Note in the databook - Section 4.4 - EEE :
" The EEE feature is not supported when the MAC is configured to use the
TBI, RTBI, SMII, RMII or SGMII single PHY interface. Even if the MAC
supports multiple PHY interfaces, you should activate the EEE mode only
when the MAC is operating with GMII, MII, or RGMII interface."

Applying this restriction solves a stability issue observed on Amlogic
gxl platforms operating with RMII interface and the internal PHY.

Fixes: 83bf79b6bb64 ("stmmac: disable at run-time the EEE if not supported")
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Tested-by: Arnaud Patard <arnaud.patard@rtp-net.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
include/linux/phy.h

index adf61a7b1b01376d17feb15fff64ea0507f3ee9f..98bbb91336e4dd8b67cd51c04ff79e31b68a6945 100644 (file)
@@ -280,8 +280,14 @@ static void stmmac_eee_ctrl_timer(unsigned long arg)
 bool stmmac_eee_init(struct stmmac_priv *priv)
 {
        unsigned long flags;
+       int interface = priv->plat->interface;
        bool ret = false;
 
+       if ((interface != PHY_INTERFACE_MODE_MII) &&
+           (interface != PHY_INTERFACE_MODE_GMII) &&
+           !phy_interface_mode_is_rgmii(interface))
+               goto out;
+
        /* Using PCS we cannot dial with the phy registers at this stage
         * so we do not support extra feature like EEE.
         */
index a04d69ab7c34074b0af65857619f8f513dde0f39..867110c9d707934c183590ca2469aae594940518 100644 (file)
@@ -683,6 +683,17 @@ static inline bool phy_is_internal(struct phy_device *phydev)
        return phydev->is_internal;
 }
 
+/**
+ * phy_interface_mode_is_rgmii - Convenience function for testing if a
+ * PHY interface mode is RGMII (all variants)
+ * @mode: the phy_interface_t enum
+ */
+static inline bool phy_interface_mode_is_rgmii(phy_interface_t mode)
+{
+       return mode >= PHY_INTERFACE_MODE_RGMII &&
+               mode <= PHY_INTERFACE_MODE_RGMII_TXID;
+};
+
 /**
  * phy_interface_is_rgmii - Convenience function for testing if a PHY interface
  * is RGMII (all variants)